#include "cps.h"

// CPS Tiles
unsigned int *CpstPal=NULL;

// Arguments for the tile draw function
unsigned int nCpstType = 0;
int nCpstX = 0, nCpstY = 0;
unsigned int nCpstTile = 0;
int nCpstFlip = 0;
short *CpstRowShift = NULL;
unsigned int CpstPmsk = 0;		// Pixel mask

int nBgHi = 0;
unsigned short  ZValue = 1;
unsigned short* ZBuf = NULL;
unsigned short* pZVal = NULL;

static int CpstOne();
static int Cps2tOne();
static int CpstOneBgHi();
static int CpstOneObjZ();
CpstOneDoFn CpstOneDoX[3]    = { CpstOne, CpstOneBgHi, Cps2tOne};
CpstOneDoFn CpstOneObjDoX[2] = { CpstOne, CpstOneObjZ};

static int CpstOne()
{
	int nFun; int nSize;
	nSize=(nCpstType&24)+8;

	if (nCpstType&CTT_CARE)
	{
		if ((nCpstType&CTT_ROWS)==0)
		{
			// Return if not visible at all
			if (nCpstX <= -nSize) return 0;
			if (nCpstX >= 384) return 0;
			if (nCpstY <= -nSize) return 0;
			if (nCpstY >= 224) return 0;
		}
		nCtvRollX=0x4000017f + nCpstX * 0x7fff;
		nCtvRollY=0x400000df + nCpstY * 0x7fff;
	}

	// Clip to loaded graphics data (we have a gap of 0x200 at the end)
	nCpstTile&=nCpsGfxMask; if (nCpstTile>=nCpsGfxLen) return 1;
	pCtvTile=CpsGfx+nCpstTile;

	// Find pLine (pointer to first pixel)
	pCtvLine=pBurnDraw + nCpstY*nBurnPitch + nCpstX*nBurnBpp;

	if (nSize==32) nCtvTileAdd=16; else nCtvTileAdd=8;

	if (nCpstFlip&2)
	{
		// Flip vertically
		if (nSize==16)      { nCtvTileAdd= -8; pCtvTile+=15* 8; }
		else if (nSize==32) { nCtvTileAdd=-16; pCtvTile+=31*16; }
		else                { nCtvTileAdd= -8; pCtvTile+= 7* 8; }
	}

	nFun =nCpstType&0x1e;
	nFun|=nCpstFlip&1;
	return CtvDoX[nFun]();
}

static int CpstOneBgHi()
{
	int nFun; int nSize;
	nSize=(nCpstType&24)+8;

	if (nCpstType&CTT_CARE)
	{
		if ((nCpstType&CTT_ROWS)==0)
		{
			// Return if not visible at all
			if (nCpstX<=-nSize) return 0;
			if (nCpstX>=384)   return 0;
			if (nCpstY<=-nSize) return 0;
			if (nCpstY>=224)   return 0;
		}
		nCtvRollX=0x4000017f + nCpstX * 0x7fff;
		nCtvRollY=0x400000df + nCpstY * 0x7fff;
	}

	// Clip to loaded graphics data (we have a gap of 0x200 at the end)
	nCpstTile&=nCpsGfxMask;
	if (nCpstTile>=nCpsGfxLen) return 1;
	pCtvTile=CpsGfx+nCpstTile;

	// Find pLine (pointer to first pixel)
	pCtvLine=pBurnDraw + nCpstY*nBurnPitch + nCpstX*nBurnBpp;

	if (nSize==32) nCtvTileAdd=16; else nCtvTileAdd=8;

	if (nCpstFlip&2)
	{
		// Flip vertically
		if (nSize==16)      { nCtvTileAdd= -8; pCtvTile+=15* 8; }
		else if (nSize==32) { nCtvTileAdd=-16; pCtvTile+=31*16; }
		else                { nCtvTileAdd= -8; pCtvTile+= 7* 8; }
	}

	nFun =nCpstType&0x1e;
	nFun|=nCpstFlip&1;
	return CtvDoXB[nFun]();
}

static int Cps2tOne()
{
	int nFun; int nSize;
	nSize=(nCpstType&24)+8;

	if (nCpstType&CTT_CARE)
	{
		if ((nCpstType&CTT_ROWS)==0)
		{
			// Return if not visible at all
			if (nCpstX <= -nSize) return 0;
			if (nCpstX >= 384)    return 0;
			if (nCpstY <= -nStartline - nSize) return 0;
			if (nCpstY >= nEndline)    return 0;
		}
		nCtvRollX=0x4000017f + nCpstX * 0x7fff;
		nCtvRollY=0x40000000 + nEndline - nStartline - 1 + (nCpstY - nStartline) * 0x7fff;
	}

	// Clip to loaded graphics data (we have a gap of 0x200 at the end)
	nCpstTile&=nCpsGfxMask; if (nCpstTile>=nCpsGfxLen) return 0;
	pCtvTile=CpsGfx+nCpstTile;

	// Find pLine (pointer to first pixel)
	pCtvLine=pBurnDraw + nCpstY*nBurnPitch + nCpstX*nBurnBpp;

	if (nSize==32) nCtvTileAdd=16; else nCtvTileAdd=8;

	if (nCpstFlip&2)
	{
		// Flip vertically
		if (nSize==16)      { nCtvTileAdd= -8; pCtvTile+=15* 8; }
		else if (nSize==32) { nCtvTileAdd=-16; pCtvTile+=31*16; }
		else                { nCtvTileAdd= -8; pCtvTile+= 7* 8; }
	}

	nFun =nCpstType&0x1e;
	nFun|=nCpstFlip&1;
	return CtvDoX[nFun]();
}

static int CpstOneObjZ()
{
	int nFun; int nSize;
	nSize=(nCpstType&24)+8;


	if (nCpstType&CTT_CARE)
	{
		if ((nCpstType&CTT_ROWS)==0)
		{
			// Return if not visible at all
			if (nCpstX <= -nSize) return 0;
			if (nCpstX >= 384)    return 0;
			if (nCpstY <= -nSize) return 0;
			if (nCpstY >= 224)    return 0;
		}
		nCtvRollX=0x4000017f + nCpstX * 0x7fff;
		nCtvRollY=0x400000df + nCpstY * 0x7fff;
	}

	// Clip to loaded graphics data (we have a gap of 0x200 at the end)
	nCpstTile&=nCpsGfxMask; if (nCpstTile>=nCpsGfxLen) return 1;
	pCtvTile=CpsGfx+nCpstTile;

	// Find pLine (pointer to first pixel)
	pCtvLine=pBurnDraw + nCpstY*nBurnPitch + nCpstX*nBurnBpp;
	pZVal=ZBuf + nCpstY*384 + nCpstX;

	if (nSize==32) nCtvTileAdd=16; else nCtvTileAdd=8;

	if (nCpstFlip&2)
	{
		// Flip vertically
		if (nSize==16)      { nCtvTileAdd= -8; pCtvTile+=15* 8; }
		else if (nSize==32) { nCtvTileAdd=-16; pCtvTile+=31*16; }
		else                { nCtvTileAdd= -8; pCtvTile+= 7* 8; }
	}

	nFun =nCpstType&0x1e;
	nFun|=nCpstFlip&1;
	return CtvDoXM[nFun]();
}
